﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Calculator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string num = "";
        Stack<string> vsFinal = new Stack<string>();//存储数字和运算符
        Stack<string> vsTemp = new Stack<string>();//暂时存储运算符

        private void onNumButtonClicked(object sender, EventArgs e)
        {
            string temp = ((Button)sender).Name;
            if (temp == "numOne")
            {
                insertNum('1');
            }
            else if(temp == "numTwo")
            {
                insertNum('2');
            }
            else if (temp == "numThree")
            {
                insertNum('3');
            }
            else if (temp == "numFour")
            {
                insertNum('4');
            }
            else if (temp == "numFive")
            {
                insertNum('5');
            }
            else if (temp == "numSix")
            {
                insertNum('6');
            }
            else if (temp == "numSeven")
            {
                insertNum('7');
            }
            else if (temp == "numEight")
            {
                insertNum('8');
            }
            else if (temp == "numNine")
            {
                insertNum('9');
            }
            else if (temp == "numZero")
            {
                insertNum('0');
            }
        }

        private void insertNum(char v)
        {
            showAnswer.Text += v;
            num += v;
        }

        private void onOpButtonClicked(object sender, EventArgs e)
        {
            string temp = ((Button)sender).Name;
            if (temp == "opAdd")
            {
                insertOp('+');
            }
            else if (temp == "opMinus")
            {
                insertOp('-');
            }
            else if (temp == "opTime")
            {
                insertOp('*');
            }
            else if (temp == "opDivide")
            {
                insertOp('/');
            }
        }

        private void insertOp(char v)
        {
            try
            {
                vsFinal.Push(num);
                if (v == '+' || v == '-')
                {
                    while (vsTemp.Count != 0)
                    {
                        vsFinal.Push(vsTemp.Pop());
                    }
                    vsTemp.Push(v.ToString());
                }
                else if(v == '*' || v == '/')
                {
                    //当栈空或者栈顶为加减号时再进栈
                    while (vsTemp.Count != 0)
                    {
                        if (vsTemp.Peek() == "*" || vsTemp.Peek() == "/")
                        {
                            vsFinal.Push(vsTemp.Pop());
                        }
                        else break;
                    }
                    vsTemp.Push(v.ToString());
                }
                else if (v == '=')
                {
                    while (vsTemp.Count > 0)
                    {
                        vsFinal.Push(vsTemp.Pop());
                    }
                }

            }catch(Exception a)
            {
                MessageBox.Show(a.Message);
                myClear();
            }
            finally
            {
                showAnswer.Text += v;
                num = "";//num变为空
            }
        }

        private void opIs_Click(object sender, EventArgs e)
        {
            insertOp('=');
            try
            {
                calculate();
            }catch(Exception a)
            {
                MessageBox.Show(a.Message);
                myClear();
            }
            finally
            {
                vsFinal.Clear();
                vsTemp.Clear();
            }
        }

        private void calculate()
        {
            //vsFinal栈中已经是后缀表达式
            List<string> vs = vsFinal.ToList();
            vs.Reverse();
            int i = 0;
            while (vs.Count() > 1)
            {
                if(vs[i]=="+"|| vs[i] == "-" || vs[i] == "*" || vs[i] == "/")
                {
                    vs[i - 2] = function(vs[i - 2], vs[i - 1], vs[i]);
                    for(int j = i - 1; j < vs.Count - 2; j++)
                    {
                        vs[j] = vs[j + 2];
                    }
                    vs.RemoveAt(vs.Count() - 2);
                    vs.RemoveAt(vs.Count() - 1);

                    i -= 2;
                }
                else
                {
                    i++;
                }
            }
            showAnswer.Text += vs[0];
            showAnswer.Text += "   ";
        }

        public string function(string v1, string v2, string v3)
        {
            double n1 = Convert.ToDouble(v1);
            double n2 = Convert.ToDouble(v2);
            double n = 0;
            if (v3 == "+")
            {
                n = n1 + n2;
            }
            else if (v3 == "-")
            {
                n = n1 - n2;
            }
            else if (v3 == "*")
            {
                n = n1 * n2;
            }
            else if (v3 == "/")
            {
                if(n2 == 0)
                {
                    throw new Exception("除数不能为0");
                }
                n = n1 / n2;
            }
            return n.ToString();
        }

        private void opCls_Click(object sender, EventArgs e)
        {
            myClear();
        }

        private void myClear()
        {
            showAnswer.Text = "";
            num = "";
            vsFinal.Clear();
            vsTemp.Clear();
        }
    }
}
